<?php
class system_controller_router {
	protected $_currentRoute;
	
	public function __construct() {
		$this->_setup();
	}
	
	/**
	 * 路由
	 * @param system_controller_request_abstract $request
	 * @return system_controller_request_abstract
	 * @throws system_controller_router_exception
	 */
	public function route(system_controller_request_abstract $request) {
		$pathInfo = $request->getPathInfo();
		$path = trim(urldecode($pathInfo), '/');
		
		$routeMatched = false;
		foreach($this->_index as $key => $route) {
			if(!!($params = $route->match($path))) {
				$this->_setRequestParams($request, $params);
				$routeMatched = true;
				$this->_currentRoute = $key;
				break;
			}
		}
		if(!$routeMatched) {
			//开始系统默认路由方式
			$route = new system_controller_router_route_default();
			if(!!($params = $route->match($path))) {
				$this->_setRequestParams($request, $params);
				$routeMatched = true;
				$this->_currentRoute = $route->getRouteIndex();
			}
		}
		if(!$routeMatched) {
			throw new system_controller_router_exception('No route matched the request', 404);
		}
		return $request;
	}
	
	protected function _setRequestParams(system_controller_request_Http $request, array $params) {
		foreach($params as $param => $value) {			
			$request->setParam($param, $value);			
			if($param === $request->getControllerKey()) {
				$request->setControllerName($value);
			}
			if($param === $request->getActionKey()) {
				$request->setActionName($value);
			}
		}
	}
	
	protected $_index = array();
	public function addRoute($index, system_controller_router_route_interface $route) {
		$this->_index[$index] = $route;
		return $this;
	}
	
	/**
	 * @return system_controller_router_route
	 */
	public function getRoute($index) {
		if(isset($this->_index[$index])) {
			return $this->_index[$index];
		} else {
			$route = new system_controller_router_route_default();
			$route->setRouteIndex($index);
			return $this->_index[$index] = $route;
		}
	}
	
	public function hasRoute($index) {
		return isset($this->_index[$index]);
	}
	
	public function getCurrentRouteIndex() {
		return $this->_currentRoute;
	}
	public function getCurrentRoute() {
		return $this->getRoute($this->getCurrentRouteIndex());
	}
	
	public function assemble($name, $data = array(), $reset = false, $encode = false, $partial = false) {
		$route = $this->getRoute($name);
		return $route->assemble($data, $reset, $encode, $partial);
	}
	
	protected function _setup() {
	}
}